<?php
/**
 * Plugin xslt: Allow display XML-File using XSLT(Processor).
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Juergen A. Lamers <jaloma.ac@googlemail.com>
 */

if (!defined('DOKU_INC'))define('DOKU_INC', realpath(dirname( __FILE__ ).'/../../../').'/');
if (!defined('DOKU_PLUGIN'))define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
require_once (DOKU_PLUGIN.'syntax.php');
require_once (DOKU_PLUGIN.'/xsltproc/xslt_helper.php');
/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_xsltproc_xsltproc extends DokuWiki_Syntax_Plugin
{

    /**
     * return some info
     */
    function getInfo()
    {
        return array (
        'author'=>'Jürgen A. Lamers',
        'email'=>'jaloma.ac@googlemail.com',
        'date'=>'2009-02-23',
        'name'=>'XSLTProc Plugin',
        'desc'=>'Use the XSLTProcessor from PHP in your Wiki.
                              Syntax: <xsltproc xml="" xsl="" (param_key_values*)/>',
        'url'=>'http://www.dokuwiki.org/plugin:xsltproc',
        'url'=>'http://dokuwiki.ich-bin-am-wandern-gewesen.de/plugin:xsltsuite',
        );
    }

    /**
     * What kind of syntax are we?
     */
    function getType()
    {
        return 'substition';
    }
    function getPType()
    {
        return 'block';
    }
    /**
     * Where to sort in to parse?
     */
    function getSort()
    {
        return 899;
    }

    /**
     * Connect pattern to lexer
     */
    function connectTo($mode)
    {
        $this->Lexer->addSpecialPattern('<'.$this->getTagName().' ?[^>\n]*/>', $mode, $this->connectName());
    }
    function getTagName()
    {
        return "xsltproc";
    }

    function connectName()
    {
        return "plugin_xsltproc_".$this->getTagName();
    }

    function matchLength()
    {
        return strlen("<".$this->getTagName()." ");
    }

    /**
     * Handle the match
     */
    function handle($match, $state, $pos, & $handler)
    {
        $match = html_entity_decode(substr($match, $this->matchLength(), -2));

        $gmap = $this->_extract_params($match);
        return array ($gmap);
    }

    /**
     * Create output
     */
    function render($mode, & $renderer, $data)
    {
        if ($mode == 'xhtml')
        {
            list ($param) = $data;
            $xmlDocument = $param['xml'];
            $xslDocument = $param['xsl'];
            $txt = "";
            if ($xmlDocument != null && $xslDocument != null)
            {
                unset ($param['xml']);
                unset ($param['xsl']);
                $param['xmlBaseDir'] = $this->getConf('xsltProcXMLBaseDir');
                $param['xslBaseDir'] = $this->getConf('xsltProcXSLBaseDir');
                $xHelper = new xslt_helper();
                $resText = $xHelper->renderXML($xmlDocument, $xslDocument, $param);
                if ($resText != null)
                {
                    $txt .= $resText;
                }
            }
            $renderer->doc .= $txt;
            if ($this->getConf('xsltProc_nocache'))
            {
                $renderer->nocache();
            }
            return true;
        }
        return false;
    }

    /**
     * extract parameters for the xsltprocessor from the parameter string
     *
     * @param   string    $str_params   string of key="value" pairs
     * @return  array                   associative array of parameters key=>value
     */
    function _extract_params($str_params)
    {
        $param = array ();
        preg_match_all('/(\w*)="(.*?)"/us', $str_params, $param, PREG_SET_ORDER);
        if (sizeof($param) == 0)
        {
            preg_match_all("/(\w*)='(.*?)'/us", $str_params, $param, PREG_SET_ORDER);
        }
        // parse match for instructions, break into key value pairs
        $gmap = array ();
        foreach ($param as $kvpair)
        {
            list ($match, $key, $val) = $kvpair;
            // No check to parameter, most of them are send to the stylesheet.
            $gmap[$key] = $val;
        }
        return $gmap;
    }
} /* CLASS */
